//
// 基于 timerfd 的纳秒级定时器 使用Epoll管理
// Created by taojiaheng on 2020/5/29.
//
/**
 *   用例
 *   Timer timerMem = Timer();
 *   TimerTask* task = new TimerTask(secondToNanosecond(1.25), 1, true);
 *   task->timer_exec_count = 5;
 *   task->setCallFuncPtr(printHello);
 *   task->setCallFuncDestroyPtr(destroyCallFunc);
 *   timerMem.addTimer(task);
 *   timerMem.run();
 */

#ifndef WEBSOCKETSERVER_TIMER_H
#define WEBSOCKETSERVER_TIMER_H
#include "../common/cdef.h"
#include "../Socket/Socket.h"
/**
 * 定时器任务类
 */
class TimerTask{
private:
    // 定时器间隔
    unsigned long long nanosecond;
    // 定时器执行的函数指针
    void(*call_func_ptr)(void *);
    // 定时器类型 1 单次定时器 2循环定时器
    char timer_type;
    // 是否在新的线程中执行定时器 如果不是可能会阻塞定时器进程
    bool is_new_thread;
    // 定时器执行完毕销毁或手动销毁时触发的回调 用于资源释放
    void(*call_func_destroy_ptr)(void *);
public:
    TimerTask(unsigned long long _nanosecond, char _timer_type, bool _is_new_thread);
    TimerTask();
    ~TimerTask();
    // 设置调用的函数指针
    void setCallFuncPtr(void (*_call_func_ptr)(void *));
    // 自定义指针 自由使用
    void * _ptr;
    // 获取定时器间隔
    unsigned long long getNanosecond();
    // 定时器fd
    int fd;
    // 定时器剩余执行的次数 只有为循环定时器时才有意义 0 代表该定时器已经死亡 -1 为无限循环 每执行一次定时器该值-1
    int timer_exec_count;
    // 获取定时器类型
    char getTimerType();
    // 执行回调函数
    void callBack();
    // 设置定时器执行完毕或手动销毁触发的回调
    void setCallFuncDestroyPtr(void (*_call_func_destroy_ptr)(void *));
    // 检查必定的参数是否设置完毕
    bool checkParameter();
    // 执行销毁回调
    void callDestroyCallBack();
};

/**
 * 定时器管理类
 */
class Timer {
private:
    // epoll 套接字
    int epoll_fd;
    // 初始化定时器
    void _init();
    // 删除定时器
    void deleteTimerTask(TimerTask *);
public:
    Timer();
    ~Timer();
    // 运行定时管理器
    void run();
    // 添加定时器
    bool addTimer(TimerTask *);
    // 处理定时器
    void disposeTimerTask(TimerTask *);
    // 从新线程中运行定时器
    static void * _run(void *);
    // 定时器全局变量
    static Timer * timer;
};
#endif //WEBSOCKETSERVER_TIMER_H
